package net.xxcxcxcx.xc_enhancedmob.render.boss_bar.column;

import net.minecraft.entity.mob.MobEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;
import net.xxcxcxcx.xc_enhancedmob.packet.dirty.DataTracking;
import net.xxcxcxcx.xc_enhancedmob.render.boss_bar.unit.CustomBossBar;
import org.jetbrains.annotations.Nullable;

import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * CustomBossBarColumn的基础
 * <p>是具体一组CustomBossbar的实现
 * <p>其本质上是一个垂直分布的多血条
 * <p>|========--------|
 * <p>|===========---|
 */
public abstract class BaseCustomBossBarColumn implements CustomBossBarColumn {
    private final DataTracking<Text> name = new DataTracking<>();
    private final DataTracking<UUID> uuid = new DataTracking<>();
    private final DataTracking<Integer> SortCount = new DataTracking<>();//sort排序
    private final DataTracking<Boolean> showname = new DataTracking<>(false);//是否要显示名称

    private CopyOnWriteArrayList<CustomBossBar> bossBars = new CopyOnWriteArrayList();
    private boolean drity;//是否需要更新

    @Override
    public void writeDrityCustomDataToNbt(NbtCompound nbt) {
        for (int i = 0; i < getBossBars().size(); i++) {
            if (!getBossBars().get(i).getDirty()) continue;
            NbtCompound nbtCompound = new NbtCompound();
            getBossBars().get(i).writeDirtyCustomDataToNbt(nbtCompound);
            getBossBars().get(i).setDirty(false);
            nbt.put(getBossBars().get(i).getUuid().getValue().toString(), nbtCompound);
        }
        if (name.getValue() != null && name.isDirty()) {
            name.setDirty(false);
            nbt.putString("name", Text.Serializer.toJson(getName().getValue()));
        }
        if (getShowname().isDirty()) {
            getShowname().setDirty(false);
            nbt.putBoolean("showname", getShowname().getValue());
        }
        if (getUuid().isDirty()) {
            getUuid().setDirty(false);
            nbt.putUuid("uuid", getUuid().getValue());
        }
        if (getSortCount().isDirty()) {
            getSortCount().setDirty(false);
            nbt.putInt("SortCount", getSortCount().getValue());
        }
    }

    @Override
    public void readDrityCustomDataFromNbt(NbtCompound nbt) {
        for (String s : nbt.getKeys()) {
            if (s.equals("name")) {
                setName(Text.Serializer.fromJson(nbt.getString("name")));
                continue;
            }
            if (s.equals("showname")) {
                setShowname(nbt.getBoolean("showname"));
                continue;
            }
            if (s.equals("uuid")) {
                setUuid(nbt.getUuid("uuid"));
                continue;
            }
            if (s.equals("SortCount")) {
                setSortCount(nbt.getInt("SortCount"));
                continue;
            }
            UUID num = UUID.fromString(s);
            CustomBossBar column = getBossBar(num);
            if (column != null) {
                column.readDirtyCustomDataFromNbt(nbt.getCompound(s));
            }
        }
    }

    @Override
    public void writeCustomDataToNbt(NbtCompound nbt) {
        for (int i = 0; i < getBossBars().size(); i++) {
            NbtCompound nbtCompound = new NbtCompound();
            getBossBars().get(i).writeCustomDataToNbt(nbtCompound);
            nbt.put(getBossBars().get(i).getUuid().getValue().toString(), nbtCompound);
        }
        if (name.getValue() != null) {
            nbt.putString("name", Text.Serializer.toJson(getName().getValue()));
        }
        nbt.putBoolean("showname", getShowname().getValue());
        nbt.putUuid("uuid", getUuid().getValue());
        nbt.putInt("SortCount", getSortCount().getValue());
    }

    @Override
    public void tick(MobEntity mobEntity) {
        for (CustomBossBar customBossBar : getBossBars()) {
            customBossBar.tick(mobEntity);
            if (customBossBar.getDirty() && !getDrity()) {
                setDrity(true);
            }
        }
    }

    @Override
    public void addBossBar(CustomBossBar customBossBar) {
        bossBars.add(customBossBar);
        setDrity(true);
    }

    @Override
    @Nullable
    public CustomBossBar getBossBar(Text name) {
        for (CustomBossBar customBossBar : getBossBars()) {
            if (customBossBar.getName().getValue().equals(name)) {
                return customBossBar;
            }
        }
        return null;
    }

    @Override
    @Nullable
    public CustomBossBar getBossBar(UUID uuid) {
        for (CustomBossBar customBossBar : getBossBars()) {
            if (customBossBar.getUuid().getValue().equals(uuid)) {
                return customBossBar;
            }
        }
        return null;
    }

    @Override
    public CopyOnWriteArrayList<CustomBossBar> getBossBars() {
        return bossBars;
    }

    @Override
    public void setBossBars(CopyOnWriteArrayList<CustomBossBar> bossBars) {
        this.bossBars = bossBars;
    }

    @Override
    public boolean getDrity() {
        return drity;
    }

    @Override
    public void setDrity(boolean drity) {
        this.drity = drity;
    }

    @Override
    public DataTracking<Text> getName() {
        return name;
    }

    @Override
    public void setName(Text name) {
        this.name.setValue(name);
        if (this.name.isDirty()) setDrity(true);
    }

    @Override
    public DataTracking<Boolean> getShowname() {
        return showname;
    }

    @Override
    public void setShowname(boolean showname) {
        this.showname.setValue(showname);
        if (this.showname.isDirty()) setDrity(true);
    }

    @Override
    public DataTracking<UUID> getUuid() {
        return uuid;
    }

    @Override
    public void setUuid(UUID uuid) {
        this.uuid.setValue(uuid);
        if (this.uuid.isDirty()) setDrity(true);
    }

    @Override
    public DataTracking<Integer> getSortCount() {
        return SortCount;
    }

    @Override
    public void setSortCount(int Count) {
        this.SortCount.setValue(Count);
        if (this.SortCount.isDirty()) setDrity(true);
    }

}
